// 构建全局的事件监听对象
var eventSystem=new EventTarget();
// 钱包返回处理结果的方法。
function methodB(res) {
	// 触发事件并传递结果
	var event = new CustomEvent('getdata' + res.id, {
		detail: res
	});
	eventSystem.dispatchEvent(event);
} 


 async function init(fullHost,address) {
	if (window.tronWeb) {
		return
	}
	if (window.UniAppJSBridge) {
		console.log('/////////////////////////////////////////////////////')
		// 先构建一个节点对象
		 // eventSystem = ;
		let originalTronWeb = new TronWeb.TronWeb({
			fullHost:fullHost,
			// headers: {
			// 	'TRON-PRO-API-KEY': '1d9818c2-6059-4013-abdc-f068a7542850'
			// },
			privateKey: "1234567891011121314151617181920"
		});
		
		// 这个节点对象是用假的私钥构建的，所以获取到的地址是错误的，与真的不一致，所以要重新获取一下。
		// 之所以只有地址要重新获取的原因代码获取的时候没有使用await，而是直接获取的，所以没办法去请求钱包
		// 所以只能提前赋值好了
		function getdefaultAddress() {
			return new Promise((resolve, reject) => {
				let id = new Date().getTime() + ''
				// 绑定监听事件
				let jianting = function(event) {
					console.log("发送时的ID:" + id)
					console.log("接收到的ID:" + event.detail.id)
					if (id == event.detail.id) {
						console.log("状态："+event.detail)
						if(event.detail.status==true){
							resolve(event.detail.data);
						}else{
							throw event.detail.data;
						}
						eventSystem.removeEventListener(
							'getdata' + event
							.detail.id, jianting
						);
					}
				}
				console.log("添加的监听事件ID:" + 'getdata' + id)
				eventSystem.addEventListener('getdata' + id, jianting);
				// 广播事件给钱包，让钱包执行
				uni.webView.postMessage({
					data: {
						level: 1,
						id: id
					}
				});
			})

		}
		originalTronWeb.defaultAddress = await getdefaultAddress()
		// 至此与tronlink钱包一致的节点对象已经注入成功了



		// 下面是通过代理的形式，监听这个DAPP对这个节点的所有请求
		// 但是并不是所有的方法都广播给钱包，经测试只需要把节点对象为trx(沟通区块的方法)和transactionBuilder(构建交易的方法)交给钱包来处理就可以
		// 前者是因为要和节点交互，这步应该由钱包完成，而且构建的节点没有真实私钥。钱包也要有对应的弹窗和授权提示。
		// 后者是因为在构建交易数据时他会从我们注入的节点中获取地址和私钥等相关信息，我们需要把他交给钱包，把假数据换成真实的。
		// 这里就有一个问题了，他会不会通过构建交易的方式来获取到用户的真正地址和私钥！！！！！！！！！！！！！！！！！！！！！
		var handler = {

			get: function(target, propKey, receiver) {
				// 获取请求的对象及对象类型
				console.log("对象:" + propKey + "对象类型" + typeof(target[propKey]))
				if (typeof(target[propKey]) == "object") {
					// 如果第一层的属性是对象类型话,我们分为两种情况处理,一种是trx和transactionBuilder的，一种是其他
					// 如果是trx,我们先把trx下面的所有方法绑上代理
					if (propKey == 'trx' || propKey == "transactionBuilder") {
						var originalTrx = target[propKey];
						// 获取到以后开始给他绑定代理
						return new Proxy(originalTrx, {
							get: function(trxTarget, trxPropKey, trxReceiver) {
								// 绑上代理后在判断是方法还是属性
								// 方法的处理逻辑
								// 
								if (typeof(originalTrx[trxPropKey]) == "function") {
									return function(...args) {
										console.log("对象:" + propKey + "方法:" + trxPropKey +
											"参数:" + args)
										// 通过异步回调的方式先绑定监听，而后广播等待结果
										return new Promise((resolve, reject) => {
											let id = new Date().getTime() + ''
											// 绑定监听事件
											let jianting = function(event) {
												console.log("发送时的ID:" + id +
													"接收到的ID:" + event
													.detail.id)

												if (id == event.detail.id) {
													console.log("状态："+event.detail.status)
													if(event.detail.status==true){
														resolve(event.detail.data);
													}else{
														// resolve(event.detail.data);
														throw event.detail.data;
														
													}
													eventSystem.removeEventListener(
														'getdata' + event
														.detail.id, jianting
													);
												}
											}
											eventSystem.addEventListener('getdata' +
												id, jianting);
											// 广播事件给钱包，让钱包执行
											console.log("内部url"+window.location.hostname)
											uni.webView.postMessage({
												data: {
													propKey,
													trxPropKey,
													args,
													type: "function",
													level: 2,
													id: id,
													url:window.location.hostname
												}
											});
										})
									}
								} else {
									// 把第一层对象是trx或transactionBuilder，但调用的不是方法的行为放在这里
									// 这里其实有点多余，因为trx和transactionBuilder全是方法，没有属性
									// 这行代码放在这里是为了思路清晰
									return Reflect.get(target, propKey, receiver);
								}
							}
						});
					} else {
						// 这里是把第一层是对象但不是trx和transactionBuilder的情况合到一起了，他们都是调用原方法
						return Reflect.get(target, propKey, receiver);
					}
				} else {
					// 原计划是第一层是方法或属性的情况分开，现在感觉没必要，所以合到一起了。
					return Reflect.get(target, propKey, receiver);

				}
			}
		};
		// 将代理与节点绑定好，然后赋值给window.tronWeb，至此window.tronWeb对象构建完毕。
		window.tron = new Proxy(originalTronWeb, handler);
		window.tron.tronWeb=new Proxy(originalTronWeb, handler);
	}
}

// // 延迟一秒执行的原因是怕对应的JS没有加载好，这里应该有方案可以优化
// setTimeout(function() {
// 	init()
// }, 1000)
